home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Vertigo / Patches / Patches68K.c next >
C/C++ Source or Header  |  2000-06-23  |  12KB  |  524 lines

  1. #define DISABLE_LOCAL_CALLTRACE        1        // Set to 1 to disable Call Traces for this file.
  2. #define DISABLE_LOCAL_DEBUG            0        // Set to 1 to disable all debugging for this file.
  3. #include "DebugUtils.h"
  4.  
  5. #include <Gestalt.h>
  6. #include <Traps.h>
  7. #include <Displays.h>
  8. #include <QuickDraw.h>
  9. #include "ContextUtils.h"
  10. #include "Nub.h"
  11. #include "PatchHarness.h"
  12. #include "ProcInfo.h"
  13.  
  14.  
  15.  
  16.  
  17.  
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21.  
  22. typedef pascal void (*CloseCPortProcPtr)(CGrafPtr port);
  23. typedef pascal void (*ClosePortProcPtr)(GrafPtr port);
  24. typedef pascal void (*OpenCPortProcPtr)(CGrafPtr port);
  25. typedef pascal void (*OpenPortProcPtr)(GrafPtr port);
  26.  
  27. enum
  28. {
  29.     _CleanUpApplication                = 0xAAFB,
  30.     _SynchIdleTime                    = 0xABF7
  31. };
  32.  
  33. pascal OSStatus main(PatchDesc **patchList);
  34. static pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch);
  35. static pascal void Remove(struct PatchDesc *desc);
  36.  
  37. static void CleanUpApplicationPatchHarness(void);
  38. static void CleanUpApplicationSetTrapAddress(UniversalProcPtr addr);
  39. static void CleanUpApplicationSetPatchAddress(UniversalProcPtr addr);
  40. static pascal void CloseCPortPatchHarness(CGrafPtr port);
  41. static pascal void ClosePortPatchHarness(GrafPtr port);
  42. static pascal void CopyBitsPatchHarness(BitMap *srcBits,BitMap *dstBits,Rect *srcRect,Rect *dstRect,short mode,RgnHandle maskRgn);
  43. static pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response);
  44. static void GestaltSetSelectorResult(SInt32 value);
  45. static pascal void OpenCPortPatchHarness(CGrafPtr port);
  46. static pascal void OpenPortPatchHarness(GrafPtr port);
  47. static void QuickTimeDispatchPatchHarness(void);
  48. static void QuickTimeDispatchSetTrapAddress(UniversalProcPtr addr);
  49. static void QuickTimeDispatchSetPatchAddress(UniversalProcPtr addr);
  50. static void SynchIdleTimePatchHarness(void);
  51. static void SynchIdleTimeSetTrapAddress(UniversalProcPtr addr);
  52. static void SynchIdleTimeSetPatchAddress(UniversalProcPtr addr);
  53.  
  54. #ifdef __cplusplus
  55. }
  56. #endif
  57.  
  58.  
  59.  
  60.  
  61.  
  62. PatchDesc                    gCleanUpApplicationDesc;
  63. PatchDesc                    gCloseCPortDesc;
  64. CloseCPortProcPtr            gCloseCPortTrap = NULL;
  65. CloseCPortPatchPtr            gCloseCPortPatch = NULL;
  66. PatchDesc                    gClosePortDesc;
  67. ClosePortProcPtr            gClosePortTrap = NULL;
  68. ClosePortPatchPtr            gClosePortPatch = NULL;
  69. PatchDesc                    gCopyBitsDesc;
  70. CopyBitsProcPtr                gCopyBitsTrap = NULL;
  71. CopyBitsPatchPtr            gCopyBitsPatch = NULL;
  72. PatchDesc                    gGestaltSelectorDesc;
  73. PatchDesc                    gOpenCPortDesc;
  74. OpenCPortProcPtr            gOpenCPortTrap = NULL;
  75. OpenCPortPatchPtr            gOpenCPortPatch = NULL;
  76. PatchDesc                    gOpenPortDesc;
  77. OpenPortProcPtr                gOpenPortTrap = NULL;
  78. OpenPortPatchPtr            gOpenPortPatch = NULL;
  79. PatchDesc                    gSynchIdleTimeDesc;
  80.  
  81.  
  82.  
  83.  
  84.  
  85. pascal OSStatus main(PatchDesc **patchList)
  86. {
  87.     GlobalContext        globals;
  88.     PatchDesc            *head = *patchList;
  89.     ProcessSerialNumber    psn;
  90.     OSStatus            err;
  91.     
  92.     
  93.     // Install Gestalt selector.
  94.     gGestaltSelectorDesc.type = 'GSEL';
  95.     gGestaltSelectorDesc.install = Install;
  96.     gGestaltSelectorDesc.remove = Remove;
  97.     gGestaltSelectorDesc.next = head;
  98.     head = &gGestaltSelectorDesc;
  99.     
  100.     err = NewGestalt(kNubSelector,GestaltSelectorHarness);
  101.     if (err != noErr)
  102.     {
  103.         OSType    selector = kNubSelector;
  104.         dprintf(kDConPrefix "NewGestalt('%.4s') failed: %ld\n",&selector,err);
  105.         return err;
  106.     }
  107.     
  108.     // Install _CleanUpApplication patch.
  109.     gCleanUpApplicationDesc.type = 'CApp';
  110.     gCleanUpApplicationDesc.install = Install;
  111.     gCleanUpApplicationDesc.remove = Remove;
  112.     gCleanUpApplicationDesc.next = head;
  113.     head = &gCleanUpApplicationDesc;
  114.     
  115.     CleanUpApplicationSetTrapAddress(NGetTrapAddress(_CleanUpApplication,ToolTrap));
  116.     NSetTrapAddress((UniversalProcPtr)CleanUpApplicationPatchHarness,_CleanUpApplication,ToolTrap);
  117.     
  118.     // Install _CloseCPort patch.
  119.     gCloseCPortDesc.type = 'ClCP';
  120.     gCloseCPortDesc.install = Install;
  121.     gCloseCPortDesc.remove = Remove;
  122.     gCloseCPortDesc.next = head;
  123.     head = &gCloseCPortDesc;
  124.     
  125.     gCloseCPortTrap = (CloseCPortProcPtr)NGetTrapAddress(_CloseCPort,ToolTrap);
  126.     NSetTrapAddress((UniversalProcPtr)CloseCPortPatchHarness,_CloseCPort,ToolTrap);
  127.     
  128.     // Install _ClosePort patch.
  129.     gClosePortDesc.type = 'CloP';
  130.     gClosePortDesc.install = Install;
  131.     gClosePortDesc.remove = Remove;
  132.     gClosePortDesc.next = head;
  133.     head = &gClosePortDesc;
  134.     
  135.     gClosePortTrap = (ClosePortProcPtr)NGetTrapAddress(_ClosePort,ToolTrap);
  136.     NSetTrapAddress((UniversalProcPtr)ClosePortPatchHarness,_ClosePort,ToolTrap);
  137.     
  138.     // Install _CopyBits patch.
  139.     gCopyBitsDesc.type = 'CBit';
  140.     gCopyBitsDesc.install = Install;
  141.     gCopyBitsDesc.remove = Remove;
  142.     gCopyBitsDesc.next = head;
  143.     head = &gCopyBitsDesc;
  144.     
  145.     gCopyBitsTrap = (CopyBitsProcPtr)NGetTrapAddress(_CopyBits,ToolTrap);
  146.     NSetTrapAddress((UniversalProcPtr)CopyBitsPatchHarness,_CopyBits,ToolTrap);
  147.     
  148.     // Install _OpenCPort patch.
  149.     gOpenCPortDesc.type = 'OpCP';
  150.     gOpenCPortDesc.install = Install;
  151.     gOpenCPortDesc.remove = Remove;
  152.     gOpenCPortDesc.next = head;
  153.     head = &gOpenCPortDesc;
  154.     
  155.     gOpenCPortTrap = (OpenCPortProcPtr)NGetTrapAddress(_OpenCPort,ToolTrap);
  156.     NSetTrapAddress((UniversalProcPtr)OpenCPortPatchHarness,_OpenCPort,ToolTrap);
  157.     
  158.     // Install _OpenPort patch.
  159.     gOpenPortDesc.type = 'OpnP';
  160.     gOpenPortDesc.install = Install;
  161.     gOpenPortDesc.remove = Remove;
  162.     gOpenPortDesc.next = head;
  163.     head = &gOpenPortDesc;
  164.     
  165.     gOpenPortTrap = (OpenPortProcPtr)NGetTrapAddress(_OpenPort,ToolTrap);
  166.     NSetTrapAddress((UniversalProcPtr)OpenPortPatchHarness,_OpenPort,ToolTrap);
  167.     
  168.     // Install _SynchIdleTime patch.
  169.     gSynchIdleTimeDesc.type = 'IDLE';
  170.     gSynchIdleTimeDesc.install = Install;
  171.     gSynchIdleTimeDesc.remove = Remove;
  172.     gSynchIdleTimeDesc.next = head;
  173.     head = &gSynchIdleTimeDesc;
  174.     
  175.     QuickTimeDispatchSetTrapAddress(NGetTrapAddress(0xAAAA,ToolTrap));
  176.     NSetTrapAddress((UniversalProcPtr)QuickTimeDispatchPatchHarness,0xAAAA,ToolTrap);
  177.     //SynchIdleTimeSetTrapAddress(NGetTrapAddress(_SynchIdleTime,ToolTrap));
  178.     //NSetTrapAddress((UniversalProcPtr)SynchIdleTimePatchHarness,_SynchIdleTime,ToolTrap);
  179.     
  180.     // Set patch list.
  181.     *patchList = head;    
  182.     return noErr;
  183. }
  184.  
  185.  
  186.  
  187.  
  188.  
  189. pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch)
  190. {
  191.     GlobalContext    globals;
  192.     
  193.     
  194.     switch(desc->type)
  195.     {
  196.         case 'CApp':
  197.             CleanUpApplicationSetPatchAddress(patch);
  198.             break;
  199.         
  200.         case 'ClCP':
  201.             gCloseCPortPatch = (CloseCPortPatchPtr)patch;
  202.             break;
  203.         
  204.         case 'CloP':
  205.             gClosePortPatch = (ClosePortPatchPtr)patch;
  206.             break;
  207.         
  208.         case 'CBit':
  209.             gCopyBitsPatch = (CopyBitsPatchPtr)patch;
  210.             break;
  211.         
  212.         case 'OpCP':
  213.             gOpenCPortPatch = (OpenCPortPatchPtr)patch;
  214.             break;
  215.         
  216.         case 'OpnP':
  217.             gOpenPortPatch = (OpenPortPatchPtr)patch;
  218.             break;
  219.         
  220.         case 'GSEL':
  221.             // Remove Gestalt selector result.
  222.             GestaltSetSelectorResult((SInt32)patch);
  223.             break;
  224.         
  225.         case 'IDLE':
  226.             QuickTimeDispatchSetPatchAddress((UniversalProcPtr)patch);
  227.             //SynchIdleTimeSetPatchAddress((UniversalProcPtr)patch);
  228.             break;
  229.         
  230.         default:
  231.             dprintf(kDConPrefix "Install: patch '%.4s' not found\n",&desc->type);
  232.             break;
  233.     }
  234. }
  235.  
  236.  
  237.  
  238.  
  239.  
  240. pascal void Remove(struct PatchDesc *desc)
  241. {
  242.     GlobalContext    globals;
  243.     
  244.     
  245.     switch(desc->type)
  246.     {
  247.         case 'CApp':
  248.             CleanUpApplicationSetPatchAddress(NULL);
  249.             break;
  250.         
  251.         case 'ClCP':
  252.             gCloseCPortPatch = NULL;
  253.             break;
  254.         
  255.         case 'CloP':
  256.             gClosePortPatch = NULL;
  257.             break;
  258.         
  259.         case 'CBit':
  260.             gCopyBitsPatch = NULL;
  261.             break;
  262.         
  263.         case 'OpCP':
  264.             gOpenCPortPatch = NULL;
  265.             break;
  266.         
  267.         case 'OpnP':
  268.             gOpenPortPatch = NULL;
  269.             break;
  270.         
  271.         case 'GSEL':
  272.             // Remove Gestalt selector result.
  273.             GestaltSetSelectorResult((SInt32)0);
  274.             break;
  275.         
  276.         case 'IDLE':
  277.             QuickTimeDispatchSetPatchAddress(NULL);
  278.             //SynchIdleTimeSetPatchAddress(NULL);
  279.             break;
  280.         
  281.         default:
  282.             dprintf(kDConPrefix "Remove: patch '%.4s' not found\n",&desc->type);
  283.             break;
  284.     }
  285. }
  286.  
  287.  
  288. #if 0
  289. #pragma mark -
  290. #endif
  291.  
  292.  
  293. asm void CleanUpApplicationPatchHarness(void)
  294. {
  295.     PEA            @1
  296.     MOVE.L        @TrapAddressStorage,-(SP)    // Put address of trap into A1.
  297.     RTS
  298.     
  299. @1:    MOVEM.L        D0-D2/A0-A1,-(A7)            // Save CPU state on stack.
  300.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  301.     CMPA.W        #0x0000,A0                    // Compare address of patch to NULL.
  302.     BEQ.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  303.     JSR            (A0)                        // Call patch code.
  304.     
  305. @CallRealTrap:
  306.     MOVEM.L        (A7)+,D0-D2/A0-A1            // Restore CPU state from stack.
  307.     RTS                                        // Return to real trap.
  308.     
  309. entry static CleanUpApplicationSetTrapAddress
  310.     LEA            @TrapAddressStorage,A0
  311.     MOVE.L        4(SP),(A0)
  312.     RTS
  313.     
  314. entry static CleanUpApplicationSetPatchAddress
  315.     LEA            @PatchAddressStorage,A0
  316.     MOVE.L        4(SP),(A0)
  317.     RTS
  318.     
  319. @TrapAddressStorage:
  320.     DC.L        0x00000000                    // Storage for trap address.
  321. @PatchAddressStorage:
  322.     DC.L        0x00000000                    // Storage for patch address.
  323. }
  324.  
  325.  
  326.  
  327.  
  328.  
  329. pascal void CloseCPortPatchHarness(CGrafPtr port)
  330. {
  331.     CloseCPortProcPtr    closeCPortTrap;
  332.     
  333.     
  334.     {
  335.         GlobalContext globals;
  336.         
  337.         closeCPortTrap = gCloseCPortTrap;
  338.         if (gCloseCPortPatch != NULL)
  339.             CallCloseCPortPatch(gCloseCPortPatch,port);
  340.     }
  341.     
  342.     closeCPortTrap(port);
  343. }
  344.  
  345.  
  346.  
  347.  
  348.  
  349. pascal void ClosePortPatchHarness(GrafPtr port)
  350. {
  351.     ClosePortProcPtr    closePortTrap;
  352.     
  353.     
  354.     {
  355.         GlobalContext globals;
  356.         
  357.         closePortTrap = gClosePortTrap;
  358.         if (gClosePortPatch != NULL)
  359.             CallClosePortPatch(gClosePortPatch,port);
  360.     }
  361.     
  362.     closePortTrap(port);
  363. }
  364.  
  365.  
  366.  
  367.  
  368.  
  369. pascal void CopyBitsPatchHarness(BitMap *srcBits,BitMap *dstBits,Rect *srcRect,Rect *dstRect,short mode,RgnHandle maskRgn)
  370. {
  371.     CopyBitsProcPtr        copyBitsTrap;
  372.     CopyBitsPatchPtr    copyBitsPatch;
  373.     
  374.     {
  375.         GlobalContext globals;
  376.         
  377.         copyBitsTrap = gCopyBitsTrap;
  378.         copyBitsPatch = gCopyBitsPatch;
  379.     }
  380.     
  381.     if (copyBitsPatch == NULL)
  382.         copyBitsTrap(srcBits,dstBits,srcRect,dstRect,mode,maskRgn);
  383.     else
  384.         copyBitsPatch(srcBits,dstBits,srcRect,dstRect,mode,maskRgn,copyBitsTrap);
  385. }
  386.  
  387.  
  388.  
  389.  
  390.                                  
  391. asm pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response)
  392. {
  393.     MOVEA.L        4(SP),A0                // Move response into A0.
  394.     MOVE.L        @ResultStorage,(A0)        // Move *ResultStorage into *response.
  395.     CLR.W        12(SP)                    // Set the return value to no error.
  396.     RTD            #8                        // Clean up pascal stack frame and return.
  397.     
  398. entry static GestaltSetSelectorResult
  399.     LEA            @ResultStorage,A0
  400.     MOVE.L        4(SP),(A0)
  401.     RTS
  402.     
  403. @ResultStorage:
  404.     DC.L        0x00000000                // 4 Byte return value.
  405. }
  406.  
  407.  
  408.  
  409.  
  410.  
  411. pascal void OpenCPortPatchHarness(CGrafPtr port)
  412. {
  413.     OpenCPortProcPtr    openCPortTrap;
  414.     
  415.     
  416.     {
  417.         GlobalContext globals;
  418.         openCPortTrap = gOpenCPortTrap;
  419.     }
  420.     
  421.     openCPortTrap(port);
  422.     
  423.     {
  424.         GlobalContext globals;
  425.         
  426.         if (gOpenCPortPatch != NULL)
  427.             CallOpenCPortPatch(gOpenCPortPatch,port);
  428.     }
  429. }
  430.  
  431.  
  432.  
  433.  
  434.  
  435. pascal void OpenPortPatchHarness(GrafPtr port)
  436. {
  437.     OpenPortProcPtr    openPortTrap;
  438.     
  439.     
  440.     {
  441.         GlobalContext globals;
  442.         openPortTrap = gOpenPortTrap;
  443.     }
  444.     
  445.     openPortTrap(port);
  446.     
  447.     {
  448.         GlobalContext globals;
  449.         
  450.         if (gOpenPortPatch != NULL)
  451.             CallOpenPortPatch(gOpenPortPatch,port);
  452.     }
  453. }
  454.  
  455.  
  456.  
  457.  
  458.  
  459. asm void QuickTimeDispatchPatchHarness(void)
  460. {
  461.     MOVEA.L        @TrapAddressStorage,A1        // Put address of trap into A1.
  462.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  463.     CMPA.W        #0x0000,A0                    // Compare address of patch to NULL.
  464.     BEQ.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  465.     CMPI.W        #0x82F0,D0
  466.     BNE.S        @CallRealTrap
  467.     
  468.     MOVEM.L        D0-D7/A1-A6,-(A7)            // Save CPU state on stack.
  469.     JSR            (A0)                        // Call patch code.
  470.     MOVEM.L        (A7)+,D0-D7/A1-A6            // Restore CPU state from stack.
  471.     
  472. @CallRealTrap:
  473.     JMP            (A1)                        // Directly jump to real trap.
  474.     
  475. entry static QuickTimeDispatchSetTrapAddress
  476.     LEA            @TrapAddressStorage,A0
  477.     MOVE.L        4(SP),(A0)
  478.     RTS
  479.     
  480. entry static QuickTimeDispatchSetPatchAddress
  481.     LEA            @PatchAddressStorage,A0
  482.     MOVE.L        4(SP),(A0)
  483.     RTS
  484.     
  485. @TrapAddressStorage:
  486.     DC.L        0x00000000                    // Storage for trap address.
  487. @PatchAddressStorage:
  488.     DC.L        0x00000000                    // Storage for patch address.
  489. }
  490.  
  491.  
  492.  
  493.  
  494.  
  495. asm void SynchIdleTimePatchHarness(void)
  496. {
  497.     MOVEA.L        @TrapAddressStorage,A1        // Put address of trap into A1.
  498.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  499.     CMPA.W        #0x0000,A0                    // Compare address of patch to NULL.
  500.     BEQ.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  501.     
  502.     MOVEM.L        D3-D7/A1-A6,-(A7)            // Save CPU state on stack.
  503.     JSR            (A0)                        // Call patch code.
  504.     MOVEM.L        (A7)+,D3-D7/A1-A6            // Restore CPU state from stack.
  505.     
  506. @CallRealTrap:
  507.     JMP            (A1)                        // Directly jump to real trap.
  508.     
  509. entry static SynchIdleTimeSetTrapAddress
  510.     LEA            @TrapAddressStorage,A0
  511.     MOVE.L        4(SP),(A0)
  512.     RTS
  513.     
  514. entry static SynchIdleTimeSetPatchAddress
  515.     LEA            @PatchAddressStorage,A0
  516.     MOVE.L        4(SP),(A0)
  517.     RTS
  518.     
  519. @TrapAddressStorage:
  520.     DC.L        0x00000000                    // Storage for trap address.
  521. @PatchAddressStorage:
  522.     DC.L        0x00000000                    // Storage for patch address.
  523. }
  524.